package com.haozi.ehub.core.config;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.haozi.ehub.entity.code.DateCode;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.format.Formatter;


/**
 * 全局设置时间bean
 * @author     ： terry
 * @date       ： Created in 2020/6/16 10:03
 */
@Configuration
public class LocalDateTimeSerializerConfig {
	/**
    * 时间格式化
    * @return ObjectMapper
    */
    @Bean
    public ObjectMapper serializingObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 对于空的对象转json的时候不抛出错误
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        // 禁用遇到未知属性抛出异常
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 序列化BigDecimal时不使用科学计数法输出
        objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);

        JavaTimeModule javaTimeModule = new JavaTimeModule();
        //序列化时间
        javaTimeModule.addSerializer(LocalDateTime.class, localDateTimeSerializer());
        javaTimeModule.addSerializer(LocalDate.class, localDateSerializer());
        javaTimeModule.addSerializer(LocalTime.class, localTimeSerializer());
        //反序列化时间
        javaTimeModule.addDeserializer(LocalDateTime.class,localDateTimeDeserializer());
        javaTimeModule.addDeserializer(LocalDate.class,localDateDeserializer());
        javaTimeModule.addDeserializer(LocalTime.class,localTimeDeserializer());
        objectMapper.registerModule(javaTimeModule);
        return objectMapper;
    }

    @Bean
    public LocalDateTimeSerializer localDateTimeSerializer() {
        return new LocalDateTimeSerializer(
                DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_2));
    }
    @Bean
    public LocalDateTimeDeserializer localDateTimeDeserializer(){
        return new LocalDateTimeDeserializer(
                DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_2));
    }

    @Bean
    public LocalDateSerializer localDateSerializer() {
        return new LocalDateSerializer(
                DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_4));
    }
    @Bean
    public LocalDateDeserializer localDateDeserializer(){
        return new LocalDateDeserializer(
                DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_4));
    }

    @Bean
    public LocalTimeSerializer localTimeSerializer() {
        return new LocalTimeSerializer(
                DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_5));
    }
    @Bean
    public LocalTimeDeserializer localTimeDeserializer(){
        return new LocalTimeDeserializer(
                DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_5));
    }


    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder ->
               builder.serializerByType(LocalDateTime.class, localDateTimeSerializer());
    }


    @Bean
    public Formatter<LocalDateTime> localDateTimeFormatter() {
        return new Formatter<LocalDateTime>() {
            @Override
            public String print(LocalDateTime object, Locale locale) {
                return object.format(DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_2));
            }

            @Override
            public LocalDateTime parse(String text, Locale locale){
                return LocalDateTime.parse(text, DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_2));
            }
        };
    }
    @Bean
    public Formatter<LocalDate> localDateFormatter() {
        return new Formatter<LocalDate>() {
            @Override
            public String print(LocalDate object, Locale locale) {
                return object.format(DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_4));
            }

            @Override
            public LocalDate parse(String text, Locale locale){
                return LocalDate.parse(text, DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_4));
            }
        };
    }

    @Bean
    public Formatter<LocalTime> localTimeFormatter() {
        return new Formatter<LocalTime>() {
            @Override
            public String print(LocalTime object, Locale locale) {
                return object.format(DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_5));
            }

            @Override
            public LocalTime parse(String text, Locale locale){
                return LocalTime.parse(text, DateTimeFormatter.ofPattern(DateCode.DATE_TIME_FORMAT_5));
            }
        };
    }
}
